home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / quarkpy / perspective.py < prev    next >
Text File  |  2004-01-05  |  7KB  |  250 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. The map editor's "Commands" menu (to be extended by plug-ins)
  4. """
  5. #
  6. # Copyright (C) 1996-99 Armin Rigo
  7. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  8. # FOUND IN FILE "COPYING.TXT"
  9.  
  10.  
  11. #$Header: /cvsroot/quark/runtime/quarkpy/perspective.py,v 1.2 2002/08/09 10:00:11 decker_dk Exp $
  12.  
  13. #
  14. # Operations for creating boxes whose face-names reflect
  15. #  their orientation in the view they're clicked on, plus
  16. #  operations for building and manipulating dictionaries.
  17. #  for accessing them.  Used for shape-from-box buildiers
  18. #  in mb2curves, mapbrushcurves, and mapstair.
  19. #
  20.  
  21. import quarkx
  22. from maputils import *
  23.  
  24. # return X, Y, Z axes:
  25. #  X to right on screen
  26. #  Y away from viewer (toward would mean lh coord sys)
  27. #  Z up on screen
  28. #
  29. #  The idea is that these should equal map coordinates in Quark's
  30. #    default side-on view.  All the sign-flips & axis swapping
  31. #    is kinda confusing.
  32. #
  33. def perspectiveAxes(view=None):
  34.     try:
  35.         if view is None:
  36.             view = quarkx.clickform.focus  # gets the mapview clicked on
  37.         x, z = view.vector("x"), -view.vector("y")
  38. #  axes = view.vector("x"), -view.vector(view.screencenter), -view.vector("y")
  39.         return map(lambda v:v.normalized, (x, (x^z), z))
  40.     except:
  41.         return map(lambda t:quarkx.vect(t), ((1,0,0), (0,-1,0), (0,0,1)))
  42.  
  43. #
  44. # return front, back, left, right, top, bottom w.r.t. view
  45. #  perspective if possible, otherwise None.
  46. #
  47. def perspectiveFaceDict(o, view):
  48.     faces = o.subitems
  49.     if len(faces)!=6:
  50.         return None
  51.     axes = perspectiveAxes(view)
  52.     pool = faces[:]
  53.     faceDict = {}
  54.     for (label, ax, dir) in (('f',1, 1)
  55.                             ,('b',1,-1)
  56.                             ,('u',2, 1)
  57.                             ,('d',2,-1)
  58.                             ,('r',0, 1)
  59.                             ,('l',0,-1)):
  60.         chosenface = pool[0]
  61.         axis = axes[ax]*dir
  62.         chosendot = chosenface.normal*axis
  63.         for face in pool[1:]:
  64.             if face.normal*axis>chosendot:
  65.                 chosenface=face
  66.                 chosendot=face.normal*axis
  67.         faceDict[label]=chosenface
  68.         pool.remove(chosenface)
  69.     return faceDict
  70.  
  71. def faceDict(o):
  72.     result = {}
  73.     for (key, name) in (('f','front')
  74.                        ,('b','back' )
  75.                        ,('u','up'   )
  76.                        ,('d','down' )
  77.                        ,('r','right')
  78.                        ,('l','left' )):
  79.         result[key]=o.findshortname(name)
  80.     return result
  81.  
  82. def perspectiveRename(o, view):
  83.     "renames the faces of a 6-face polyhedron in accord with perspective of last-clicked-on view"
  84.     dict = perspectiveFaceDict(o, view)
  85.     if dict is None:
  86.         return None
  87.     newpoly = quarkx.newobj(o.name)
  88.     for (key, name) in (('f','front')
  89.                        ,('b','back' )
  90.                        ,('u','up'   )
  91.                        ,('d','down' )
  92.                        ,('r','right')
  93.                        ,('l','left' )):
  94.         newface = dict[key].copy()
  95.         newface.shortname = name
  96.         newpoly.appenditem(newface)
  97.     return newpoly
  98.  
  99. def othervect(vector, vecpair):
  100.   "returns member of vecpair that is different from vector"
  101.   if (vector-vecpair[0]):
  102.     return vecpair[0]
  103.   else:
  104.     return vecpair[1]
  105.  
  106. def splitpoints(edge1, edge2):
  107.   "if edge1 & edge2 share a point, returns shared, edge1 non-shared, edge2 non-shared"
  108.   common = shared_vertices([edge1, edge2])[0]
  109.   if common is None:
  110.     return None
  111. #  squawk("removeing")
  112.   first = othervect(common, edge1)
  113. #  squawk("first")
  114.   second = othervect(common,edge2)
  115. #  squawk("second")
  116. #  squawk(`first`+"--"+`second`)
  117.   return common, first, second
  118.  
  119. def pointdict(dict):
  120.   points = {}
  121.   front, up, left = dict["f"], dict["u"], dict["l"]
  122. #  squawk('ful')
  123.   topfront = shared_vertices([front, up])
  124. #  squawk('tf')
  125.   topleft = shared_vertices([left, up])
  126.   points["tlf"], points["trf"], points["tlb"]=splitpoints(topfront, topleft)
  127.   right, down, back = dict["r"], dict["d"], dict["b"]
  128.   frontright = shared_vertices([right, front])
  129.   bottomfront = shared_vertices([front,down])
  130. #  tagedge(frontright[0], frontright[1], editor)
  131.   points["brf"], points["blf"], points["trf"] = splitpoints(bottomfront, frontright)
  132.   bottomback = shared_vertices([down, back])
  133.   rightback = shared_vertices([right, back])
  134.   points["brb"], points["trb"], points["blb"] = splitpoints(rightback, bottomback)
  135.   return points
  136.  
  137.  
  138. #
  139. # Might be better to code this with remove? Except that
  140. #  I suspect that list.remove won't work for vectors.
  141. #
  142. def shared_vertices(vtxlists):
  143.   "returns list of vertices that appear in every list of vtxlists"
  144.   first = vtxlists[0]
  145.   for vtxlist in vtxlists[1:]:
  146.     second=[]
  147.     for vtx in first:
  148.       for vtx2 in vtxlist:
  149.         if not(vtx-vtx2):
  150.            second.append(vtx)
  151.            break
  152.     first=second
  153.   return first
  154.  
  155.  
  156. def vtxlistdict(faceDict,o):
  157.     "returns a dict in which the keys are associated with vertex-lists"
  158.     result = {}
  159. #    squawk('doing '+`o.shortname`)
  160.     try:
  161.         for key in faceDict.keys():
  162. #            squawk('key: '+`key`+'; '+faceDict[key].shortname)
  163.             result[key]=faceDict[key].verticesof(o)
  164.     except (AttributeError):
  165.         return None
  166.     return result
  167.  
  168.  
  169. def pointdict_vflip(pd):
  170.     "flips the pointdict upside down"
  171.     flipdict = {'t':'b', 'b':'t'}
  172.     pd2 = {}
  173.     for key in pd.keys():
  174.         key2 = "%s%s%s"%(flipdict[key[0]],key[1],key[2])
  175.         pd2[key2] = pd[key]
  176.     return pd2
  177.  
  178. def pointdict_hflip(pd):
  179.     "flips the pointdict left-to-right"
  180.     flipdict = {'l':'r', 'r':'l'}
  181.     pd2 = {}
  182.     for key in pd.keys():
  183.         key2 = "%s%s%s"%(key[0],flipdict[key[1]],key[2])
  184.         pd2[key2] = pd[key]
  185.     return pd2
  186.  
  187. def pointdict_rflip(pd):
  188.     "rotates pointdict so that front becomes top"
  189.     pd2 = {}
  190.     pd2["trf"], pd2["tlf"] = pd["brf"], pd["blf"]
  191.     pd2["trb"], pd2["tlb"] = pd["trf"], pd["tlf"]
  192.     pd2["brb"], pd2["blb"] = pd["trb"], pd["tlb"]
  193.     pd2["brf"], pd2["blf"] = pd["brb"], pd["blb"]
  194.     return pd2
  195.  
  196. def facedict_rflip(fd):
  197.     fd2 = {}
  198.     for key in ('l', 'r'):
  199.         fd2[key]=fd[key]
  200.     fd2['u']=fd['f']
  201.     fd2['b']=fd['u']
  202.     fd2['d']=fd['b']
  203.     fd2['f']=fd['d']
  204.     return fd2
  205.  
  206. def facedict_spin(fd):
  207.     fd2 = {}
  208.     for key in ('u', 'd'):
  209.         fd2[key]=fd[key]
  210.     fd2['f']=fd['b']
  211.     fd2['b']=fd['f']
  212.     fd2['r']=fd['l']
  213.     fd2['l']=fd['r']
  214.     return fd2
  215.  
  216. def facedict_fflip(fd):
  217.     "flips facedict front-back"
  218.     fd2 = {}
  219.     for key in ('u','d','r','l'):
  220.         fd2[key]=fd[key]
  221.     fd2['f']=fd['b']
  222.     fd2['b']=fd['f']
  223.     return fd2
  224.  
  225. def facedict_hflip(fd):
  226.     "flips the facedict left-to-right"
  227.     fd2 = {}
  228.     for key in ('f','b','u','d'):
  229.         fd2[key]=fd[key]
  230.     fd2['r']=fd['l']
  231.     fd2['l']=fd['r']
  232.     return fd2
  233.  
  234. def facedict_vflip(fd):
  235.     "flips the facedict upside-down"
  236.     fd2 = {}
  237.     for key in ('f','b','r','l'):
  238.         fd2[key]=fd[key]
  239.     fd2['u']=fd['d']
  240.     fd2['d']=fd['u']
  241.     return fd2
  242.  
  243. #$Log: perspective.py,v $
  244. #Revision 1.2  2002/08/09 10:00:11  decker_dk
  245. #A minor consistency correction for facedict_*flip()
  246. #
  247. #Revision 1.1  2001/02/14 10:06:47  tiglari
  248. #extracted from mb2curves, etc
  249. #
  250.